<?php

namespace addons\csmitsm\library\xcore\xcflow\utils;

use addons\csmitsm\library\sdnode\xstack\utils\XsJsonUtils;
use think\Db;
use addons\csmitsm\library\xcore\xcore\utils\XcDaoUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcDatabaseUtils;
use addons\csmitsm\library\xcore\xcore\XcException;

class XcflowToMdmUtils
{

    /**
     * @return array
     */
    public static function generateCreateTableMdmfieldjsonFromXcflowTable($xcflow)
    {
        $result = null;
        $mdmfieldkeys = [];
        if (true) {
            // $mdmfieldjsonobj = json_decode($xcflow->mdmfieldjson, true);
            $mdmfieldjsonobj = XsJsonUtils::stringToJson($xcflow->mdmfieldjson);
            if ($mdmfieldjsonobj) {
                foreach ($mdmfieldjsonobj as $field) {
                    $result[] = $field;
                    $mdmfieldkeys[] = $field['flowfieldcode'];
                }
            }
        }

        // $xcfieldjsonObj = json_decode($xcflow->xcfieldjson, true);
        $xcfieldjsonObj = XsJsonUtils::stringToJson($xcflow->xcfieldjson);
        if ($xcfieldjsonObj) {
            foreach ($xcfieldjsonObj as $field) {
                if (!in_array($field['fieldcode'], $mdmfieldkeys)) {
                    $result[] = [
                        "flowfieldcode" => $field['fieldcode'],
                        "mdmfieldcode" => $field['fieldcode'],
                        "pk" => 0,
                        "status" => 1
                    ];
                }
            }
        }

        return $result;
    }

    public static function createOrUpdateFromXcflowdata($xcform_id, $xcflowData)
    {
        $mdmData = null;

        $xcflow = XcDaoUtils::getRowById(new \app\admin\model\csmitsm\Xcflow(), $xcform_id);
        $xcfieldjsonObj = XcformFieldsUtils::getXcfieldjsonJsonObjectFromXcform($xcflow);

        $tablename = $xcflow->mdmtablename;
        if (empty($tablename)) {
            return null;
        }
        // main flow -> mdm
        if (isset($xcflowData['xcflow_mdmdata_id'])) {
            $mdmData = XcflowToMdmUtils::getById($xcflowData['xcflow_id'], $xcflowData['id']);
            if ($mdmData) {
                $mdmData = static::updateFromXcflowdata($xcform_id, $xcflowData);
            }
        } else {
            // by pk config
            $findMdmRow = null;
            if (true) {
                $whereCount = 0;
                $sql = Db::table($tablename);
                // $mdmfieldjsonObj = json_decode($xcflow->mdmfieldjson, true);
                $mdmfieldjsonObj = XsJsonUtils::stringToJson($xcflow->mdmfieldjson);
                foreach ($mdmfieldjsonObj as $field) {
                    if ($field['pk'] == "1") {
                        $sql->where($field['mdmfieldcode'], $xcflowData[$field['flowfieldcode']]);
                        $whereCount++;
                    }
                }
                if ($whereCount > 0) {
                    $findMdmRow = $sql->find();
                }
            }

            if ($findMdmRow) {
                $xcflowData['xcflow_mdmdata_id'] = $findMdmRow['id'];
                $mdmData = static::updateFromXcflowdata($xcform_id, $xcflowData);
            } else {
                $mdmData = static::createFromXcflowdata($xcform_id, $xcflowData);
            }
        }
        // sub flow List -> mdm sub List
        foreach ($xcfieldjsonObj as $field) {
            if ($field['fieldtag'] == "xcform_control_input_subtable") {
                $flowsub_data_tablename = $field['fieldjsonObj']["xcform_base_property_input_subtable"]["tablename"];
                $sub_tableForginfieldcode = $field['fieldjsonObj']["xcform_base_property_input_subtable"]["subtableForginfieldcode"];
                $sub_xcflow = XcflowallformUtils::getXcformByTablename($flowsub_data_tablename);
                $sub_xcfieldjsonObj = XcformFieldsUtils::getXcfieldjsonJsonObjectFromXcform($sub_xcflow);
                $flowsub_data_list = XcformDataUtils::getPagedatasByTablename($flowsub_data_tablename, $sub_xcfieldjsonObj, [[$sub_tableForginfieldcode, '=', $xcflowData['id']]]);
                static::createOrUpdateFromXcflowsubdatas($flowsub_data_tablename, $sub_xcflow, $flowsub_data_list, $sub_tableForginfieldcode, $xcflowData['id']);
            }
        }
        // throw new XcException("");
        return $mdmData;
    }

    public static function createOrUpdateFromXcflowsubdatas($flowsub_data_tablename, $sub_xcform, $flowsub_data_list, $sub_tableForginfieldcode, $sub_tableForginfieldvalue)
    {
        $mdmsub_tablename = XcDatabaseUtils::getFactTablename($sub_xcform->mdmtablename);
        if (empty($mdmsub_tablename)) {
            return;
        }

        $sub_list_ids = null;
        if (true) {
            $sub_list_ids = XcDaoUtils::getValuesFromList($flowsub_data_list, "id");
            $instance_subtables = XcDaoUtils::getListBySql(new \app\admin\model\csmitsm\XcflowInstanceSubtable(), [
                ["xcflow_id", "=", $sub_xcform->id],
                ["flowsub_tablename", "=", $flowsub_data_tablename],
                ["flowsub_data_id", 'in', $sub_list_ids]
            ]);
            XcDaoUtils::bindListColumn2list($flowsub_data_list, "flowsub_data_id", $instance_subtables, "mdmdata_data_id", "subflow_info");
        }

        // $mdmfieldjsonObj = json_decode($sub_xcform->mdmfieldjson, true);
        $mdmfieldjsonObj = XsJsonUtils::stringToJson($sub_xcform->mdmfieldjson);

        $insertFields = [];
        if (true) {
            foreach ($mdmfieldjsonObj as $config) {
                $insertFields[] = $config['mdmfieldcode'];
            }
        }

        $toSaveMdmModels = [];
        if (true) {
            foreach ($flowsub_data_list as $flowsub_data) {
                $mdmdata_data_id = isset($flowsub_data_list['subflow_info_mdmdata_data_id']) ? $flowsub_data_list['subflow_info_mdmdata_data_id'] : null;
                $toSaveMdmModel = ["id" => $mdmdata_data_id, "flowsub_data_id" => $flowsub_data['id']];
                foreach ($mdmfieldjsonObj as $config) {
                    if ($config['status'] == 1) {
                        $toSaveMdmModel[$config['mdmfieldcode']] = $flowsub_data[$config['flowfieldcode']];
                    }
                }
                $toSaveMdmModels[] = $toSaveMdmModel;
            }
        }
        $toSaveMdmModels = XcDatabaseUtils::createOrUpdateOrDeleteDatas($mdmsub_tablename, $toSaveMdmModels, ["id"], "mdmdata_data_id", $insertFields, [[$sub_tableForginfieldcode, "=", $sub_tableForginfieldvalue]]);

        // to save XcflowInstanceSubtable
        $toSyncInstanceSubtableModels = [];
        foreach ($toSaveMdmModels as $toSaveMdmModel) {
            $toSyncInstanceSubtableModels[] = [
                'xcflow_id' => $sub_xcform->id,
                'flowsub_tablename' => $flowsub_data_tablename,
                'flowsub_data_id' => $toSaveMdmModel['flowsub_data_id'],
                'mdmdata_data_id' => $toSaveMdmModel['mdmdata_data_id']
            ];
        }
        XcDaoUtils::createOrUpdateOrDeleteDatas(new \app\admin\model\csmitsm\XcflowInstanceSubtable(), $toSyncInstanceSubtableModels, ["xcflow_id", "flowsub_tablename", "flowsub_data_id"], null, null, [
            ['xcflow_id', "=", $sub_xcform->id],
            ['flowsub_tablename', "=", $flowsub_data_tablename]
        ]);
    }

    public static function createFromXcflowdata($xcform_id, $xcflowData)
    {
        $xcflow = XcDaoUtils::getRowById(new \app\admin\model\csmitsm\Xcflow(), $xcform_id);

        $mdmXcform = XcflowallformUtils::getXcformByTablename($xcflow->mdmtablename);
        $mdm_xcfieldjsonObj = XcformFieldsUtils::getXcfieldjsonJsonObjectFromXcform($mdmXcform);

        $createmdm_xcfieldjsonObj = [];
        if (true) {
            // $mdmfieldjsonObj = json_decode($xcflow->mdmfieldjson, true);
            $mdmfieldjsonObj = XsJsonUtils::stringToJson($xcflow->mdmfieldjson);
            foreach ($mdmfieldjsonObj as $mdmfield) {
                foreach ($mdm_xcfieldjsonObj as $field) {
                    if ($field["fieldcode"] == $mdmfield['mdmfieldcode']) {
                        $createmdm_xcfieldjsonObj[] = $field;
                    }
                }
            }
        }
        return XcformDataUtils::createData($xcflow->mdmtablename, $createmdm_xcfieldjsonObj, $xcflowData);
    }

    public static function updateFromXcflowdata($xcform_id, $xcflowData)
    {
        $$xcflow = XcDaoUtils::getRowById(new \app\admin\model\csmitsm\Xcflow(), $xcform_id);
        // $mdmfieldjsonObj = json_decode($xcflow->mdmfieldjson, true);
        $mdmfieldjsonObj = XsJsonUtils::stringToJson($xcflow->mdmfieldjson);
        return XcformDataUtils::updateData($xcflow->mdmtablename, $mdmfieldjsonObj, $rowId, $xcflowData);
    }


    public static function getById($xcflow_id, $xcflowdataId)
    {
        $xcflow = XcDaoUtils::getRowById(new \app\admin\model\csmitsm\Xcflow(), $xcflow_id);
        $xcfieldjsonObj = XcformFieldsUtils::getXcfieldjsonJsonObjectFromXcform($xcflow);
        return XcformDataUtils::getPagedataByTablenameAndRowid($xcflow->mdmtablename, $xcfieldjsonObj, $xcflowdataId);
    }
}
